/*
 * Copyright© 2003-2019 浙江汇信科技有限公司, All Rights Reserved.
 */
package com.icinfo.cloud.provider.punish.csource.manage.service.impl;

import com.icinfo.cloud.common.security.util.UserUtil;
import com.icinfo.cloud.provider.common.constant.Constant;
import com.icinfo.cloud.provider.common.enums.ApiVisitDataSourceEnum;
import com.icinfo.cloud.provider.common.exception.BusinessException;
import com.icinfo.cloud.provider.peripheralinterface.taskcenter.dto.TripartiteStatusDto;
import com.icinfo.cloud.provider.peripheralinterface.taskcenter.service.ITaskCenterService;
import com.icinfo.cloud.provider.punish.csource.manage.dto.CaseSourceCluHandoutRecordDto;
import com.icinfo.cloud.provider.punish.csource.manage.dto.CaseSourceHandleInfoDto;
import com.icinfo.cloud.provider.punish.csource.manage.dto.CaseSourceHandlePersonRecordSaveDto;
import com.icinfo.cloud.provider.punish.csource.manage.dto.FlowCommonDto;
import com.icinfo.cloud.provider.punish.csource.manage.dto.docdata.CaseSourceAppointInfo;
import com.icinfo.cloud.provider.punish.csource.manage.enums.CaseSourceOperateTypeEnum;
import com.icinfo.cloud.provider.punish.csource.manage.enums.CaseSourceStatusEnum;
import com.icinfo.cloud.provider.punish.csource.manage.enums.FlowStageTypeEnum;
import com.icinfo.cloud.provider.punish.csource.manage.mapper.CaseSourceCluHandoutRecordMapper;
import com.icinfo.cloud.provider.punish.csource.manage.mapper.CaseSourceRegisterMainInfoMapper;
import com.icinfo.cloud.provider.punish.csource.manage.model.AppointedPersonInfo;
import com.icinfo.cloud.provider.punish.csource.manage.model.CaseSourceCluHandoutRecord;
import com.icinfo.cloud.provider.punish.csource.manage.model.CaseSourceRegisterMainInfo;
import com.icinfo.cloud.provider.punish.csource.manage.service.ICaseSourceCluHandoutRecordService;
import com.icinfo.cloud.provider.punish.csource.manage.service.ICaseSourceFlowRecordService;
import com.icinfo.cloud.provider.punish.csource.manage.service.ICaseSourceHandlePersonRecordService;
import com.icinfo.cloud.provider.punish.csource.manage.service.ICaseSourceRegisterMainInfoService;
import com.icinfo.cloud.provider.punish.evideinv.dto.CaseSourceEventSaveDto;
import com.icinfo.cloud.provider.punish.evideinv.service.EvidenceInventoryService;
import com.icinfo.cloud.xzcf.provider.member.userinfo.dto.UserDTO;
import com.icinfo.framework.common.web.Result;
import com.icinfo.framework.core.service.support.MyBatisServiceSupport;
import com.icinfo.framework.mybatis.mapper.entity.Example;
import com.icinfo.framework.tools.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 描述: 案源线索派发记录表（含分派+指派） case_source_clu_handout_record 对应的Service接口实现类.<br>
 *
 * @author framework generator
 * @date 2022年08月12日
 */
@Slf4j
@Service
public class CaseSourceCluHandoutRecordServiceImpl extends MyBatisServiceSupport implements ICaseSourceCluHandoutRecordService {
    /**
     * 日志记录器
     */
    private static final Logger logger = LoggerFactory.getLogger(CaseSourceCluHandoutRecordServiceImpl.class);

    @Resource
    private CaseSourceCluHandoutRecordMapper caseSourceCluHandoutRecordMapper;

    @Resource
    private CaseSourceRegisterMainInfoMapper caseSourceRegisterMainInfoMapper;

    @Resource
    private ICaseSourceFlowRecordService caseSourceFlowRecordService;

    @Resource
    private ICaseSourceHandlePersonRecordService caseSourceHandlePersonRecordService;

    @Resource
    private EvidenceInventoryService evidenceInventoryService;
    @Resource
    private ICaseSourceRegisterMainInfoService caseSourceRegisterMainInfoService;
    @Resource
    private ITaskCenterService taskCenterService;
    /**
     * 案源分派保存接口
     * @param caseSourceCluHandoutRecordDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveCaseSourceAssign(CaseSourceCluHandoutRecordDto caseSourceCluHandoutRecordDto) {

        UserDTO userInfo = UserUtil.getUserInfo();
        CaseSourceCluHandoutRecord caseSourceCluHandoutRecord = new CaseSourceCluHandoutRecord();
        BeanUtils.copyProperties(caseSourceCluHandoutRecordDto, caseSourceCluHandoutRecord);
        caseSourceCluHandoutRecord.setId(StringUtils.uuid());
        caseSourceCluHandoutRecord.setCluAssignUserOrgCode(userInfo.getOrgCode());
        caseSourceCluHandoutRecord.setCluAssignUserOrgName(userInfo.getOrgName());
        caseSourceCluHandoutRecord.setCluAssignUserName(userInfo.getRealName());
        caseSourceCluHandoutRecord.setCluAppointUserId(userInfo.getUserId().toString());
        caseSourceCluHandoutRecord.setCluAppointTime(new Date());
        int count = 0;
        // 待分派状态下直接新增
        if (CaseSourceStatusEnum.TO_DISPATCH.getIndex().equals(caseSourceCluHandoutRecordDto.getCaseSourceStatus())){
            count = caseSourceCluHandoutRecordMapper.insertSelective(caseSourceCluHandoutRecord);
        }
        // 已下发进行更改
        if (CaseSourceStatusEnum.HAS_BEEN_ISSUED.getIndex().equals(caseSourceCluHandoutRecordDto.getCaseSourceStatus())){
            this.validation(caseSourceCluHandoutRecord, userInfo);
            Example example = new Example(CaseSourceCluHandoutRecord.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("caseSourceId",caseSourceCluHandoutRecord.getCaseSourceId());
            criteria.andEqualTo("cluAssignUserOrgCode",userInfo.getOrgCode());
            count = caseSourceCluHandoutRecordMapper.updateByExampleSelective(caseSourceCluHandoutRecord,example);
        }

        // 更新案源主表信息
        this.updateCaseSourceRegisterMainInfo(caseSourceCluHandoutRecordDto,userInfo,FlowStageTypeEnum.CASE_SOURCE_ASSIGN.getIndex());

        // 新增案源流程记录
        this.saveCaseSourceCommonFlowRecord(caseSourceCluHandoutRecordDto,userInfo,FlowStageTypeEnum.CASE_SOURCE_ASSIGN.getIndex());

        return count;
    }

    private void validation(CaseSourceCluHandoutRecord caseSourceCluHandoutRecord, UserDTO userInfo) {
        Example example = new Example(CaseSourceCluHandoutRecord.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("caseSourceId",caseSourceCluHandoutRecord.getCaseSourceId());
        criteria.andIsNotNull("cluAssignedOrgCode");
        List<CaseSourceCluHandoutRecord> records = caseSourceCluHandoutRecordMapper.selectByExample(example);
        if (records.size() >= Constant.INTEGER_2){
            throw new BusinessException("案源分发失败");
        }
        Example example1 = new Example(CaseSourceCluHandoutRecord.class);
        Example.Criteria criteria1 = example1.createCriteria();
        criteria1.andEqualTo("caseSourceId",caseSourceCluHandoutRecord.getCaseSourceId());
        criteria1.andIsNotNull("cluAppointedMainPersonId");
        List<CaseSourceCluHandoutRecord> caseSourceCluHandoutRecords = caseSourceCluHandoutRecordMapper.selectByExample(example1);
        if (CollectionUtils.isNotEmpty(caseSourceCluHandoutRecords)){
            throw new BusinessException("案源分发失败,案源已指派办案人员");
        }
    }

    /**
     * 案源指派保存
     * @param caseSourceCluHandoutRecordDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveCaseSourceAppoint(CaseSourceCluHandoutRecordDto caseSourceCluHandoutRecordDto) {

        UserDTO userInfo = UserUtil.getUserInfo();
        CaseSourceCluHandoutRecord caseSourceCluHandoutRecord = new CaseSourceCluHandoutRecord();
        BeanUtils.copyProperties(caseSourceCluHandoutRecordDto, caseSourceCluHandoutRecord);
        caseSourceCluHandoutRecord.setId(StringUtils.uuid());
        caseSourceCluHandoutRecord.setCluAppointUserOrgCode(userInfo.getOrgCode());
        caseSourceCluHandoutRecord.setCluAppointUserOrgName(userInfo.getOrgName());
        caseSourceCluHandoutRecord.setCluAppointUserName(userInfo.getRealName());
        caseSourceCluHandoutRecord.setCluAppointUserId(userInfo.getUserId().toString());
        caseSourceCluHandoutRecord.setCluAssignTime(new Date());
        int count = caseSourceCluHandoutRecordMapper.insertSelective(caseSourceCluHandoutRecord);

        // 更新案源主表信息
        this.updateCaseSourceRegisterMainInfo(caseSourceCluHandoutRecordDto, userInfo,FlowStageTypeEnum.CASE_SOURCE_APPOINT.getIndex());

        // 新增案源流程记录
        this.saveCaseSourceCommonFlowRecord(caseSourceCluHandoutRecordDto, userInfo,FlowStageTypeEnum.CASE_SOURCE_APPOINT.getIndex());

        // 新增案源办案人员记录
        this.saveCaseSourceHandlePersonRecord(caseSourceCluHandoutRecordDto, userInfo);

        // 新增案源事件
        this.saveCaseSourceEvent(caseSourceCluHandoutRecordDto);

        CaseSourceHandleInfoDto caseSourceHandleInfoDto=new CaseSourceHandleInfoDto();
        BeanUtils.copyProperties(caseSourceCluHandoutRecordDto,caseSourceCluHandoutRecord);
        //生成案源登记表文书
        CaseSourceAppointInfo appointInfo=new CaseSourceAppointInfo();
        appointInfo.setCluAppointUserId(userInfo.getUserId().toString());
        appointInfo.setCluAppointUserName(userInfo.getRealName());
        appointInfo.setCluAppointDesc(caseSourceCluHandoutRecordDto.getCluAppointDesc());
        appointInfo.setCluAssignDate(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年M月d日")));
        caseSourceRegisterMainInfoService.saveCaseSourceRegisterDoc(caseSourceCluHandoutRecordDto.getCaseSourceId(), CaseSourceOperateTypeEnum.APPOINT.getCode(),appointInfo);
        return count;
    }


    /**
     * 更新案源主表信息
     * @param caseSourceCluHandoutRecordDto
     * @param type
     */
    private void updateCaseSourceRegisterMainInfo(CaseSourceCluHandoutRecordDto caseSourceCluHandoutRecordDto,UserDTO userInfo, String type){
        CaseSourceRegisterMainInfo caseSourceRegisterMainInfo = new CaseSourceRegisterMainInfo();
        caseSourceRegisterMainInfo.setId(caseSourceCluHandoutRecordDto.getCaseSourceId());
        caseSourceRegisterMainInfo.setDealTime(new Date());
        caseSourceRegisterMainInfo.setHandleOrgName(caseSourceCluHandoutRecordDto.getCluAssignedOrgName());
        // 案源分配已下发
        if (FlowStageTypeEnum.CASE_SOURCE_ASSIGN.getIndex().equals(type)){
            caseSourceRegisterMainInfo.setCaseSourceStatus(CaseSourceStatusEnum.HAS_BEEN_ISSUED.getIndex());
            caseSourceRegisterMainInfo.setCaseSourceStageCode(Constant.CASE_SOURCE_STAGE_AYFP);
        }
        // 案源指派预调查
        if (FlowStageTypeEnum.CASE_SOURCE_APPOINT.getIndex().equals(type)){
            caseSourceRegisterMainInfo.setCaseSourceStatus(CaseSourceStatusEnum.PRE_SURVEY.getIndex());
            caseSourceRegisterMainInfo.setCaseSourceStageCode(Constant.CASE_SOURCE_STAGE_AYZP);
            caseSourceRegisterMainInfo.setHandlePersonMainId(caseSourceCluHandoutRecordDto.getCluAppointedMainPersonId());
            caseSourceRegisterMainInfo.setHandlePersonMainName(caseSourceCluHandoutRecordDto.getCluAppointedMainPersonName());
            caseSourceRegisterMainInfo.setHandlePersonAssistId(caseSourceCluHandoutRecordDto.getCluAppointedAssistPersonId());
            caseSourceRegisterMainInfo.setHandlePersonAssistName(caseSourceCluHandoutRecordDto.getCluAppointedAssistPersonName());
            caseSourceRegisterMainInfo.setLineCode(caseSourceCluHandoutRecordDto.getLineCode());
            caseSourceRegisterMainInfo.setLineName(caseSourceCluHandoutRecordDto.getLineName());
            caseSourceRegisterMainInfo.setHandleOrgName(caseSourceCluHandoutRecordDto.getPersonOrgName());
            caseSourceRegisterMainInfo.setHandleOrgCode(UserUtil.getUserInfo().getOrgCode());
            caseSourceRegisterMainInfo.setHandleDeptCode(caseSourceCluHandoutRecordDto.getCluAppointedMainPersonDeptCode());
            caseSourceRegisterMainInfo.setHandleDeptName(caseSourceCluHandoutRecordDto.getCluAppointedMainPersonDeptName());
            caseSourceRegisterMainInfo.setBusiParamId(caseSourceRegisterMainInfoService.getBusiParamId(caseSourceCluHandoutRecordDto.getLineCode(),userInfo.getAreaCode()));
        }
        caseSourceRegisterMainInfoMapper.updateByPrimaryKeySelective(caseSourceRegisterMainInfo);

        //通知协同案源状态变更
        sendDisposalBackResult(caseSourceCluHandoutRecordDto.getCaseSourceId());
    }

    /**
     * 新增案源办案人员记录
     */
    private void saveCaseSourceHandlePersonRecord(CaseSourceCluHandoutRecordDto caseSourceCluHandoutRecordDto, UserDTO userInfo){
        CaseSourceHandlePersonRecordSaveDto dto = new CaseSourceHandlePersonRecordSaveDto();
        dto.setCaseSourceId(caseSourceCluHandoutRecordDto.getCaseSourceId());
        dto.setHandlePersonName(caseSourceCluHandoutRecordDto.getCluAppointedMainPersonName());
        dto.setHandlePersonType(Constant.STRING_1);
        dto.setHandlePersonId(caseSourceCluHandoutRecordDto.getCluAppointedMainPersonId());
        dto.setHandleOrgName(caseSourceCluHandoutRecordDto.getPersonOrgName());
        dto.setHandleOrgCode(userInfo.getOrgCode());
        dto.setHandleDeptName(caseSourceCluHandoutRecordDto.getCluAppointedMainPersonDeptName());
        dto.setHandleDeptCode(caseSourceCluHandoutRecordDto.getCluAppointedMainPersonDeptCode());
        caseSourceHandlePersonRecordService.saveCaseSourceHandlePersonRecord(dto);
        dto.setHandlePersonName(caseSourceCluHandoutRecordDto.getCluAppointedAssistPersonName());
        dto.setHandleDeptName(caseSourceCluHandoutRecordDto.getCluAppointedAssistPersonDeptName());
        dto.setHandleDeptCode(caseSourceCluHandoutRecordDto.getCluAppointedAssistPersonDeptCode());
        dto.setHandlePersonType(Constant.STRING_2);
        dto.setHandlePersonId(caseSourceCluHandoutRecordDto.getCluAppointedAssistPersonId());
        caseSourceHandlePersonRecordService.saveCaseSourceHandlePersonRecord(dto);
    }

    /**
     * 新增案源流转记录
     * @param caseSourceCluHandoutRecordDto
     * @param userInfo
     */
    private void saveCaseSourceCommonFlowRecord(CaseSourceCluHandoutRecordDto caseSourceCluHandoutRecordDto, UserDTO userInfo, String type){
        FlowCommonDto dto = new FlowCommonDto();
        dto.setCaseSourceId(caseSourceCluHandoutRecordDto.getCaseSourceId());
        dto.setFlowStartTime(new Date());
        dto.setFlowEndTime(new Date());
        dto.setStartPersonName(userInfo.getRealName());
        dto.setStartPersonOrgName(userInfo.getOrgName());
        dto.setStartPersonDeptName(userInfo.getDeptName());
        if (FlowStageTypeEnum.CASE_SOURCE_ASSIGN.getIndex().equals(type)){
            dto.setFlowStageType(Constant.CASE_SOURCE_STAGE_AYFP);
            dto.setEndOrgName(caseSourceCluHandoutRecordDto.getCluAssignedOrgName());
            dto.setCommonExplain(caseSourceCluHandoutRecordDto.getCluAssignDesc());
        }
        if (FlowStageTypeEnum.CASE_SOURCE_APPOINT.getIndex().equals(type)){
            dto.setFlowStageType(Constant.CASE_SOURCE_STAGE_AYZP);
            dto.setCommonExplain(caseSourceCluHandoutRecordDto.getCluAppointDesc());
            List<AppointedPersonInfo> list= new ArrayList<>();
            list.add(new AppointedPersonInfo(caseSourceCluHandoutRecordDto.getCluAppointedMainPersonName(),caseSourceCluHandoutRecordDto.getPersonOrgName(),caseSourceCluHandoutRecordDto.getCluAppointedMainPersonDeptName()));
            list.add(new AppointedPersonInfo(caseSourceCluHandoutRecordDto.getCluAppointedAssistPersonName(),caseSourceCluHandoutRecordDto.getPersonOrgName(),caseSourceCluHandoutRecordDto.getCluAppointedAssistPersonDeptName()));
            dto.setAppointedPersonInfoList(list);
        }
        caseSourceFlowRecordService.saveCommonFlowRecord(dto);
    }

    /**
     * 新增案源事件
     * @param caseSourceCluHandoutRecordDto
     */
    private void saveCaseSourceEvent(CaseSourceCluHandoutRecordDto caseSourceCluHandoutRecordDto) {
        try {
            CaseSourceRegisterMainInfo caseSourceRegisterMainInfo = new CaseSourceRegisterMainInfo();
            caseSourceRegisterMainInfo.setId(caseSourceCluHandoutRecordDto.getCaseSourceId());
            CaseSourceRegisterMainInfo mainInfo = caseSourceRegisterMainInfoMapper.selectOne(caseSourceRegisterMainInfo);
            CaseSourceEventSaveDto dto = new CaseSourceEventSaveDto();
            dto.setCaseSourceId(mainInfo.getId());
            dto.setCaseSourceName(mainInfo.getCaseSourceName());
            evidenceInventoryService.saveCaseSourceEvent(dto);
        } catch (Exception e) {
            logger.error("新增案源事件失败", e);
        }
    }

    /**
     * 推送案源状态至协同
     * @param caseId
     * @return
     */
    public Result sendDisposalBackResult(String caseId) {
        //协同转案源的需要回传处置结果
        log.info("开始处理需要回传处置结果的案源");
        //查询案源信息
        CaseSourceRegisterMainInfo mainInfo = caseSourceRegisterMainInfoMapper.selectByPrimaryKey(caseId);
        if (!ObjectUtils.isEmpty(mainInfo) && ApiVisitDataSourceEnum.TASKCENTER_TRANSFER.getCode().equals(mainInfo.getCaseSourceAppId())) {
            log.info("开始协同转处罚的需要回传处置结果处理");
            TripartiteStatusDto statusDto = new TripartiteStatusDto();
            statusDto.setRelUid(caseId);
            statusDto.setRelStatus(mainInfo.getCaseSourceStatus());
            statusDto.setRelStatusName(CaseSourceStatusEnum.getValue(mainInfo.getCaseSourceStatus()));
            Result result = taskCenterService.tripartiteStatusByRelUid(statusDto);
            log.info(" 修改协同的案件移送状态(协同)返回结果:{}", result);
            return result;
        } else {
            log.info("来源未配置结果回传, 无需处理");
        }
        return Result.success(Constant.STRING_SUCCESS_EN);
    }

}
